package com.qishenyuan.competition.service.impl;

import com.qishenyuan.competition.constant.FileNameConstant;
import com.qishenyuan.competition.constant.SymbolicScalarConstant;
import com.qishenyuan.competition.exception.BusinessErrorType;
import com.qishenyuan.competition.exception.BusinessException;
import com.qishenyuan.competition.service.OssService;
import com.qishenyuan.competition.utils.AliOssUtil;
import lombok.extern.slf4j.Slf4j;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class OssServiceImpl implements OssService {

    private final static String IMAGE_FOLDER = "image_test/";

    @Override
     public boolean isImageFile(String extension) {
        return FileNameConstant.JPG.equals(extension) ||
                FileNameConstant.JPEG.equals(extension) ||
                FileNameConstant.PNG.equals(extension);
    }

    @Override
    public String getFormatName(String filename) {
        String extension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        switch (extension) {
            case "png":
                return FileNameConstant.PNG;
            case "jpg":
                return FileNameConstant.JPG;
            case "jpeg":
                return FileNameConstant.JPEG;
            default:
                throw new BusinessException(BusinessErrorType.IMAGE_FORMAT_ERROR);
        }
    }

    @Override
    public byte[] compressImage(MultipartFile file) {
        try {
            BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
            if (bufferedImage == null) {
                log.warn("无法读取图片内容: {}", file.getOriginalFilename());
                return null;
            }

            int width = bufferedImage.getWidth();
            int height = bufferedImage.getHeight();
            if (width > 800) {
                double aspectRatio = (double) height / width;
                width = 800;
                height = (int) (width * aspectRatio);
            }

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Thumbnails.of(bufferedImage)
                    .size(width, height)
                    .outputQuality(0.8)
                    .outputFormat(getFormatName(Objects.requireNonNull(file.getOriginalFilename())))
                    .toOutputStream(baos);

            return baos.toByteArray();
        } catch (IOException e) {
            log.error("压缩图片失败: {}", file.getOriginalFilename(), e);
            return null;
        }
    }

    @Override
    public Map<String, List<String>> upload(MultipartFile[] files) {
        List<String> filePaths = new ArrayList<>();
        List<String> objectNames = new ArrayList<>();
        for (MultipartFile file : files) {
            log.info("准备上传文件: {}", file.getOriginalFilename());
            try {
                String originalFilename = file.getOriginalFilename();
                String extension = null;
                if (originalFilename != null) {
                    extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
                }
                if (extension != null && isImageFile(extension)) {
                    log.info("文件 {} 是图片，开始压缩", originalFilename);
                    byte[] compressedBytes = compressImage(file);
                    if (compressedBytes == null) {
                        log.warn("图片压缩失败，使用原始文件上传: {}", originalFilename);
                        compressedBytes = file.getBytes();
                    }
                    String objectName = IMAGE_FOLDER + UUID.randomUUID() + SymbolicScalarConstant.DOT + extension;
                    String filePath = AliOssUtil.upload(compressedBytes, objectName);
                    if (StringUtils.isBlank(filePath)) {
                        throw new BusinessException(BusinessErrorType.UPLOAD_FILE_FAILED);
                    }
                    filePaths.add(filePath);
                    objectNames.add(objectName);
                    log.info("图片上传成功: {}", filePath);
                }
            } catch (IOException e) {
                log.error("上传文件失败: {}", file.getOriginalFilename(), e);
            } catch (Exception e) {
                if (e instanceof BusinessException) {
                    throw new BusinessException(BusinessErrorType.UPLOAD_FILE_FAILED);
                }
                throw new RuntimeException(e);
            }
        }
        Map<String, List<String>> map = new HashMap<>();
        map.put("filePaths", filePaths);
        map.put("objectNames", objectNames);
        return map;
    }

    @Override
    public void deleteFile(String objectName) {
        log.info("deleteFile from OSS, objectName: {}", objectName);
        AliOssUtil.delete(objectName);
    }
}
